package cc.shacocloud.mirage.restful;

import io.vertx.core.Future;
import io.vertx.core.buffer.Buffer;
import org.jetbrains.annotations.Nullable;

/**
 * 调用处理器，为处理当前请求的实际调用对象，其中包含当前请求所绑定的一系列组件。
 * 在请求调用过程中，使用{@link #invokeAndHandleHandlerMethod(RoutingContext, HandlerMethod, Object...)}
 * 或者{@link #resultHandle(Object, HandlerMethod, HttpResponse)}方法来利用当前请求绑定的组件来调用指定的方法做处理
 */
public interface VertxInvokeHandler {
    
    /**
     * {@link RoutingContext#put(String, Object)}方法的{@code key}名称，该值包含可用于映射处理程序的  producible 中介类型集。
     */
    String PRODUCIBLE_MEDIA_TYPES_ATTRIBUTE = RoutingContext.INTERNAL_PARAMETERS_PREFIX + VertxInvokeHandler.class.getName() + "_producibleMediaTypes";
    
    /**
     * 调用当前路由上下文真实映射到的方法进行处理，并且对结果进行解析
     *
     * @param routingContext 当前上下文
     * @param providedArgs   根据类型封装的参数
     * @return {@link Future} 方法的执行解析后的结果
     * @see #invokeAndHandleHandlerMethod(RoutingContext, HandlerMethod, Object...)
     */
    Future<Object> invokeAndHandleRoutingContext(RoutingContext routingContext, Object... providedArgs);
    
    /**
     * 调用指定方法进行执行，并且对结果进行解析
     *
     * @param routingContext 当前上下文
     * @param handlerMethod  指定的需要被处理的对象
     * @param providedArgs   根据类型封装的参数
     * @return {@link Future} 方法的执行解析后的结果
     * @see #resultHandle
     */
    Future<Object> invokeAndHandleHandlerMethod(RoutingContext routingContext, HandlerMethod handlerMethod, Object... providedArgs);
    
    /**
     * 调用当前上下文映射的处理方法处理响应，并且返回方法的执行解析后的结果
     *
     * @param result   结果
     * @param response 响应
     * @return {@link Future} 方法的执行解析后的结果
     */
    Future<Buffer> resultHandle(@Nullable Object result, HttpResponse response);
    
    /**
     * 调用指定处理方法执行，并且返回方法的执行解析后的结果
     *
     * @param result   结果
     * @param response 响应
     * @return {@link Future} 方法的执行解析后的结果
     */
    Future<Buffer> resultHandle(Object result, HandlerMethod handlerMethod, HttpResponse response);
    
    /**
     * @return 返回处理当前请求的处理程序
     * @see HandlerMethod
     * @see InvocableHandlerMethod
     * @see VertxInvocableHandlerMethod
     */
    Object getHandler();
    
}
